home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / ast_comp / gopher.lha / gopher1.01 / gopherd / daemon.c < prev    next >
C/C++ Source or Header  |  1992-05-18  |  4KB  |  178 lines

  1. /*
  2.  *******************************************************************
  3.  * $Author: jmsellens $
  4.  * $Revision: 1.2 $
  5.  * $Date: 1992/02/10 07:36:28 $
  6.  * $Source: /source2/gopher/gopher0.7/server/RCS/daemon.c,v $
  7.  *******************************************************************
  8.  */
  9.  
  10. #include "gopherd.h"
  11.  
  12. #if defined(_AIX)  /** AIX needs bsd signals.  **/
  13. #define _BSD
  14. #endif
  15.  
  16. #define BSD 1       /* System V signal handling doesn't seem to work
  17.                Correctly */
  18.  
  19. /*
  20.  * A BSD style SIGCLD signal handler that can be used by a server
  21.  * that's not interested in its child's exit status, but needs to
  22.  * wait for them, to avoid clogging up the system with zombies.
  23.  *
  24.  * Beware that the calling process may get an interrupted system
  25.  * call when we return, so they had better handle that.
  26.  *
  27.  * (From Stevens pg 82)
  28.  */
  29.  
  30. #include <sys/ioctl.h>
  31. #include <sys/wait.h>
  32. #include <signal.h>
  33. /* some machines don't have SIGCLD defined */
  34. #ifndef SIGCLD
  35. #define SIGCLD        SIGCHLD
  36. #endif
  37.  
  38. #ifdef hpux
  39. #define TIOCNOTTY       _IO('t', 113)           /* void tty association */
  40. #endif
  41.  
  42. void
  43. sig_child()
  44. {
  45. #ifdef BSD
  46.      /*
  47.       * Use the wait3() system call with the WNOHANG option
  48.       */
  49.  
  50.      int pid;
  51.      union wait  status;
  52.  
  53.      while ( (pid = wait3(&status, WNOHANG, (struct rusage *) 0)) > 0)
  54.       ;
  55. #endif
  56. }
  57.  
  58.  
  59. #include <stdio.h>
  60. #include <sys/param.h>
  61. #include <errno.h>
  62. extern int errno;
  63.  
  64. #ifdef SIGTSTP    /* True on a BSD system */
  65. #include <sys/file.h>
  66. #include <sys/ioctl.h>
  67. #endif
  68.  
  69. /*
  70.  * Detach a daemon process from login session context
  71.  */
  72.  
  73. daemon_start(ignsigcld)
  74. int ignsigcld;          /* Nonzero -> nuke zombie children */
  75. {
  76.      register int childpid, fd;
  77.  
  78.      /*
  79.       * If we were started by init (process 1) from the /etc/inittab
  80.       * file there's no need to detach.
  81.       */
  82.       
  83.      if (getppid() != 1) {
  84.  
  85.       
  86.  
  87. #ifdef SIGTTOU
  88.       signal(SIGTTOU, SIG_IGN);
  89. #endif
  90. #ifdef SIGTTIN
  91.       signal(SIGTTIN, SIG_IGN);
  92. #endif
  93. #ifdef SIGTSTP
  94.       signal(SIGTSTP, SIG_IGN);
  95. #endif
  96.  
  97.       /*
  98.        * If we were not started in the background, fork and let
  99.        * the parent exit.  This also guarantees the first child
  100.        * is not a process group leader.
  101.        */
  102.  
  103.       if ( (childpid = fork()) < 0)
  104.            err_sys("can't fork first child");
  105.       else if (childpid >0)
  106.            exit(0);     /* parent */
  107.       
  108.       /*
  109.        * First Child process
  110.        *
  111.        * Disassociate from controlling terminal and process group.
  112.        * Ensure the process can't reacquire a new controlling terminal
  113.        */
  114.       
  115. #ifdef SIGTSTP  /* BSD */
  116.       
  117. #ifdef hpux
  118.       setsid();
  119. #else
  120.       if (setpgrp(0, getpid()) == -1)
  121.            err_sys("can't change process group");
  122.       
  123.       if ( (fd = uopen("/dev/tty", O_RDWR)) >= 0) {
  124.            ioctl(fd, TIOCNOTTY, (char *)NULL); /* lose controlling TTY*/
  125.            close(fd);
  126.       }
  127. #endif /* hpux */
  128.       
  129. #else /* System V */
  130.       
  131.       if (setpgrp() == -1)
  132.            err_sys("Can't change process group");
  133.       
  134.       signal(SIGHUP, SIG_IGN);  /* immune from pgrp leader death */
  135.       
  136.       if ( (childpid = fork()) < 0)
  137.            err_sys("Can't fork second child");
  138.       else if (childpid > 0)
  139.            exit(0); /* First child */
  140.       
  141.       /* second child */
  142. #endif
  143.  
  144.      }  /* End of if test for ppid == 1 */
  145.  
  146.      /** Close any file descriptors **/
  147.  
  148.      for (fd = 0; fd < NOFILE; fd++)
  149.       close(fd);
  150.  
  151.      errno = 0;  /* probably set to EBADF from a close */
  152.  
  153.  
  154.      /** Change the current directory to / **/
  155.  
  156.      /* No need for this, since we're already where we want to be */
  157.      /* rchdir("/"); */
  158.  
  159.      /** Clear inherited file mode creation mask. **/
  160.  
  161.      umask(0);
  162.  
  163.      /*
  164.       * See if the caller isn't ineterested in the exit status of its
  165.       * children, and doesn't want to have them become zombies
  166.       */
  167.  
  168.      if (ignsigcld) {
  169. #ifdef SIGTSTP
  170.       void sig_child();
  171.  
  172.       signal(SIGCLD, sig_child);  /* BSD */
  173. #else
  174.       signal(SIGCLD, SIG_IGN);    /* System V */
  175. #endif
  176.      }
  177. }
  178.